﻿#include <QDebug>
#include <QApplication>
#include <QDirIterator>
#include <ctkPluginContext.h>
#include <ctkPluginFramework.h>
#include <ctkPluginException.h>
#include <ctkPluginFrameworkFactory.h>
#include <ctkPluginFrameworkLauncher.h>
#include <QThread>
#include <log4qt/propertyconfigurator.h>
#include <log4qt/logmanager.h>
#include <service/pluginAdmin/pluginadmin.h>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    qDebug() << Q_FUNC_INFO << QThread::currentThread();

    //日志系统
    if(0)
    {
        QString log4qtConfig = QString("config/log.conf");
        Log4Qt::PropertyConfigurator::configure(log4qtConfig);
        Log4Qt::LogManager::setHandleQtMessages(true);
        Log4Qt::Logger::rootLogger()->info("程序启动");
    }

    //框架启动
    QString path = QCoreApplication::applicationDirPath() + "/plugins";
    ctkPluginFrameworkLauncher::addSearchPath(path,true);
    ctkProperties properties;
    properties.insert(ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN, ctkPluginConstants::FRAMEWORK_STORAGE_CLEAN_ONFIRSTINIT);
    ctkPluginFrameworkFactory fwFactory(properties);
    QSharedPointer<ctkPluginFramework> framework = fwFactory.getFramework();

    try {
        framework->init();
        framework->start();
    } catch (const ctkPluginException& exc) {
        qCritical() << QLatin1String("插件框架启动失败。") << exc;
        return -1;
    }

    //安装插件
    //获取插件上下文
    ctkPluginContext* pluginContext = framework->getPluginContext();
    QStringList libFilter;

#if defined(Q_OS_WIN)
    libFilter << "*.dll";
#elif defined(Q_OS_LINUX)
    libFilter << "*.so";
#elif defined(Q_OS_MAC)
    libFilter << "*.dylib";
#endif
    QDirIterator dirIter(path, libFilter, QDir::Files);
    QString fileLocation;
    while(dirIter.hasNext()) {
        try {
            fileLocation = dirIter.next();
            qDebug() << Q_FUNC_INFO << fileLocation;
            pluginContext->installPlugin(QUrl::fromLocalFile(fileLocation));
        }
        catch (const ctkPluginException& exc) {
            qCritical() << Q_FUNC_INFO << fileLocation << exc.what();
            return -1;
        }
    }

    //启动插件
    foreach (const QSharedPointer<ctkPlugin> &plugin, pluginContext->getPlugins()) {
        try {
            plugin->start();
        }
        catch (const ctkPluginException& exc) {
            qCritical() << exc.what();
            return -1;
        }
    }

    //插件管理
    PluginAdmin *pluginAdmin = nullptr;
    ctkServiceReference pluginAdminRef = pluginContext->getServiceReference<PluginAdmin>();
    pluginAdmin = qobject_cast<PluginAdmin *>(pluginContext->getService(pluginAdminRef));
    if(pluginAdminRef)
    {
        pluginContext->ungetService(pluginAdminRef);
    }
    if(nullptr != pluginAdmin)
    {
        pluginAdmin->setPluginFramework(framework);
    }

    return a.exec();
}
